package org.wx.herostory.services;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.wx.herostory.services.db.MySqlSessionFactory;
import org.wx.herostory.services.decoder.GameMsgRecognizer;
import org.wx.herostory.services.encoder.CmdHandlerFactory;
import org.wx.herostory.services.handler.ServerInitializer;
import org.wx.herostory.services.util.RedisUtil;
import org.wx.herostory.services.util.mq.MqProducer;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @description: 英雄传说服务端启动类
 * @author: Wang.Xun
 * @createDate: 2021/3/1
 * @version: 1.0
 */
@Slf4j
public class Server implements Runnable{
    private final InetSocketAddress inetSocketAddress;

    public Server(InetSocketAddress inetSocketAddress) {
        this.inetSocketAddress = inetSocketAddress;
    }

    @Override
    public void run() {
        // 识别器初始化
        GameMsgRecognizer.init();
        // 消息类型和处理器初始化
        CmdHandlerFactory.init();
        // 数据库连接初始化
        MySqlSessionFactory.init();
        // Redis 初始化
        RedisUtil.init();
        // mq Producer 初始化
        MqProducer.init();

        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ServerInitializer());

            ChannelFuture bind = serverBootstrap.bind(inetSocketAddress);
            bind.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if(future.isSuccess()){
                        log.info("服务器开启成功...");
                    }
                }
            });
            bind.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.error(e.getMessage(),e);
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        Server server = new Server(new InetSocketAddress("127.0.0.1", 12345));
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(server);

    }
}
